﻿namespace XGameLibrary.Controls
{
    using System;
    using System.Collections.Generic;

    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using Microsoft.Xna.Framework.Input;

    using XGameLibrary.Input;

    public class ControlManager : List<Control>
    {
        public ControlManager(SpriteFont spriteFont) :
            base()
        {
            ControlManager.SpriteFont = spriteFont;
        }

        public ControlManager(SpriteFont spriteFont, int capacity) :
            base(capacity)
        {
            ControlManager.SpriteFont = spriteFont;
        }

        public ControlManager(SpriteFont spriteFont, IEnumerable<Control> collection) :
            base(collection)
        {
            ControlManager.SpriteFont = spriteFont;
        }

        public event EventHandler FocusChanged;

        public static SpriteFont SpriteFont { get; private set; }

        private int SelectedControl { get; set; }

        public void Update(GameTime gameTime)
        {
            if (this.Count == 0)
            {
                return;
            }

            foreach (Control ctrl in this)
            {
                if (ctrl.Enabled)
                {
                    ctrl.Update(gameTime);
                }

                if (ctrl.HasFocus)
                {
                    ctrl.HandleInput();
                }
            }

            if (InputHandler.KeyPressed(Keys.Up))
            {
                this.PreviousControl();
                Control.Select.Play();
            }

            if (InputHandler.KeyPressed(Keys.Down))
            {
                this.NextControl();
                Control.Select.Play();
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            foreach (Control ctrl in this)
            {
                if (ctrl.Visible)
                {
                    ctrl.Draw(spriteBatch);
                }
            }
        }

        public void PreviousControl()
        {
            if (this.Count == 0)
            {
                return;
            }

            int currentControl = this.SelectedControl;
            this[this.SelectedControl].HasFocus = false;

            do
            {
                this.SelectedControl--;

                if (this.SelectedControl < 0)
                {
                    this.SelectedControl = this.Count - 1;
                }

                if (this[this.SelectedControl].TabStop && this[this.SelectedControl].Enabled)
                {
                    if (this.FocusChanged != null)
                    {
                        this.FocusChanged(this[this.SelectedControl], null);
                    }

                    break;
                }
            }
            while (currentControl != this.SelectedControl);

            this[this.SelectedControl].HasFocus = true;
        }

        public void NextControl()
        {
            if (this.Count == 0)
            {
                return;
            }

            int currentControl = this.SelectedControl;
            this[this.SelectedControl].HasFocus = false;

            do
            {
                this.SelectedControl++;

                if (this.SelectedControl == this.Count)
                {
                    this.SelectedControl = 0;
                }

                if (this[this.SelectedControl].TabStop && this[this.SelectedControl].Enabled)
                {
                    if (this.FocusChanged != null)
                    {
                        this.FocusChanged(this[this.SelectedControl], null);
                    }

                    break;
                }
            }
            while (currentControl != this.SelectedControl);

            this[this.SelectedControl].HasFocus = true;
        }
    }
}
